// SPDX-License-Identifier: GPL-2.0 or GPL-3.0
// Copyright © 2018-2019 Ariadne Devos
/* shttpd - TCP/IP listening sockets associated with tasks */

#ifndef _sHT_ACCEPT_H
#define _sHT_ACCEPT_H

#include <sHT/task.h>

struct sHT_worker;
struct sHT_task_stream;

/* A TCP/IP listening socket */
struct sHT_passive
{
	int fd;
	int max_accept_iterations;
};

struct sHT_task_accept
{
	struct sHT_task task;
	struct sHT_passive accept;
};

/* Allocate a task for a connection that might be returned by
   accept(2). NULL is considered to be an allocation failure.

   It is up to this function to set worker->flags error flags. */
__attribute__((warn_unused_result))
__attribute__((nonnull (1, 2)))
struct sHT_task_stream *
sHT_accept_subtask(struct sHT_worker *worker, struct sHT_task_accept *task);

/* subtask has been allocated by sHT_accept_subtask, with the listening socket
   being task, but no connection has been accepted by accept(2). Free subtask.
 */
__attribute__((nonnull (1, 2, 3)))
void
sHT_accept_abort(struct sHT_worker *worker, struct sHT_task_accept *task, struct sHT_task_stream *subtask);

/* child->stream.fd is set. task can choose what to do with it. task is not
   automatically scheduled in case of possible IO. child has been allocated by
   sHT_accept_subtask. */
__attribute__((nonnull (1, 2, 3)))
void
sHT_accept_logic(struct sHT_worker *worker, struct sHT_task_accept *task, struct sHT_task_stream *child);

__attribute__((nonnull (1, 2)))
void
sHT_accept_task(struct sHT_worker *worker, struct sHT_task_accept *task);

#endif
